/**
*  \file global.c
*
*  \brief
*
*  \author Dajin Li
*
*
*/
/*===============================================[ private includes  ]================================================*/
#include "global.h"
#include "stm32f10x.h"

/*===============================================[ private defines   ]================================================*/
/*===============================================[ private datatypes ]================================================*/

/*===============================================[ private variables ]================================================*/

/*===============================================[ public variables  ]================================================*/
u8 key_status;
PinCodeType Pin_Code;
Screen_Mode_type Screen_Mode;
Screen_Mode_type PRV_Screen_Mode;//Store the provise mode before switch
u8 task_status[TASK_MAX];		// Flags to indicate health (status) of each task
u16 TechPwd_KWP;
u16 ServicePwd_KWP;
u8 in_menu = 0;
u8 CAN_Time_Out = 0;
u8 LanguageSelect;
u8 LongEnterPressed = 0;
u8 NeedReset = 0;
u16 speedometer_units;      // 0: km 1: miles
u16 date_code;
u16 hardware_revision;
u16 key_status_op;
s8  LCD_Bklight;
int LCD_AdjustbarExitCounter = 0;
u8 CRC8_POLY = 0x31;
u8 crc8_init = 0xa5;
const char * const unitstr_enu[MAX_NUM_UNITS] =
{
    " ",               // 0
    "mV",              // 1
    "ms",              // 2
    "Nm",              // 3
    "V",               // 4
    "%",               // 5
    "kPag",            // 6
    "C",               // 7
    "revs",            // 8
    "kPaa",            // 9
    "kW",              // 10
    "Deg",             // 11
    "rpm",             // 12
    "hrs"              // 13 
};

/*================================================[ private functions ]================================================*/

/*================================================[ inline functions ]================================================*/


/*================================================[ public functions ]================================================*/

/**
* @brief	delay function
* @param	u16 time: delay time
* @param	none
* @note     none
* @retval   none
*/
void Delay (u16 time)
{
	vu16 j;
	
	IWDG_ReloadCounter();
	for(j = 0; j < time; j++)
    {
        ;
    }
	IWDG_ReloadCounter();
}
/**
* @brief	Increment_InRange
* @param	s16 var
* @param	s16 min_range
* @param	s16 max_range
* @note     none
* @retval   none
*/
s16 Increment_InRange(s16 var, s16 min_range, s16 max_range)
{
    var++;
    if (var > max_range)
    {		  
        var = min_range;
    }		 
    return(var);
}
/**
* @brief	Decrement_InRange
* @param	u16 time: delay time
* @param	s16 var
* @param	s16 min_range
* @param	s16 max_range
* @note     none
* @retval   none
*/
s16 Decrement_InRange(s16 var, s16 min_range, s16 max_range)
{
    if( var <= min_range )	
    {  
        var = max_range;
    }		 
    else
    { 
        var--;
    }
    return(var);
}

/**
* @brief	lookup KWP2000 obejct id 
* @param	const s32 *table
* @param	s16 length
* @param	s32 target
* @note     none
* @retval   none
*/
s16 lookup_object_id(kwp_data_st *table, s16 length, s32 target)
{
    int high = length;
    int low = -1;
    int probe = 0;

    while (high - low > 1) 
    {                                  
        probe = (high + low) / 2;       
        if (table[probe].kwp_id < target)
        {
            low = probe;
        }
        else
        {
            high = probe;
        }
    }

    if (high == length || table[high].kwp_id != target) 
    {
        return -1;                     
    }
    else
    {
        return high;                    
    }
}

/**
* @brief	lookup KWP2000 obejct id 
* @param	const s32 *table
* @param	s16 length
* @param	s32 target
* @note     none
* @retval   none
*/
s16 lookup_const_object_id(const kwp_data_st *table, s16 length, s32 target)
{
    int high = length;
    int low = -1;
    int probe = 0;

    while (high - low > 1) 
    {                                  
        probe = (high + low) / 2;       
        if (table[probe].kwp_id < target)
        {
            low = probe;
        }
        else
        {
            high = probe;
        }
    }

    if (high == length || table[high].kwp_id != target) 
    {
        return -1;                     
    }
    else
    {
        return high;                    
    }
}


/**
* @brief	lookup KWP2000 obejct id 
* @param	const s32 *table
* @param	s16 length
* @param	s32 target
* @note     none
* @retval   none
*/
s16 lookup_gateway_object_id(const kwp_gateway_data_st *table, s16 length, s32 target)
{
    int high = length;
    int low = -1;
    int probe = 0;

    while (high - low > 1) 
    {                                  
        probe = (high + low) / 2;       
        if (table[probe].kwp_id < target)
        {
            low = probe;
        }
        else
        {
            high = probe;
        }
    }

    if (high == length || table[high].kwp_id != target) 
    {
        return -1;                     
    }
    else
    {
        return high;                    
    }
}




/**
* @brief	look up J1939 fault message description based on the CAN object id
* @param	E_fault_msg_st *table: fault message table
* @param	s16 length: table length
* @param	s32 target: target object id
* @note     none
* @retval   none
*/
s16 lookup_fmi_object_id(const J1939_fault_msg_st *table, s16 length, s32 target)
{
    int high = length;
    int low = -1;
    int probe = 0;

    while (high - low > 1) 
    {                                  
        probe = (high + low) / 2;       
        if (table[probe].fault_id < target)
        {
            low = probe;
        }
        else
        {
            high = probe;
        }
    }

    if (high == length || table[high].fault_id != target) 
    {
        return -1;                     
    }
    else
    {
        return high;                    
    }
}
/**
* @brief	look up truck fault message description based on the CAN object id
* @param	E_fault_msg_st *table: fault message table
* @param	s16 length: table length
* @param	s32 target: target object id
* @note     none
* @retval   none
*/
s16 lookup_truck_fault_object_id(const Truck_fault_msg_st *table, s16 length, s32 target)
{
    int high = length;
    int low = -1;
    int probe = 0;

    while (high - low > 1) 
    {                                  
        probe = (high + low) / 2;       
        if (table[probe].fault_id < target)
        {
            low = probe;
        }
        else
        {
            high = probe;
        }
    }

    if (high == length || table[high].fault_id != target) 
    {
        return -1;                     
    }
    else
    {
        return high;                    
    }
}

/**
* @brief	look up CANopen ojbect based on the CAN object id
* @param	E_fault_msg_st *table: fault message table
* @param	s16 length: table length
* @param	s32 target: target object id
* @note     none
* @retval   none
*/
s16 lookup_CAN_object_id(CAN_param_st *table, s16 length, s32 target)
{
    int high = length;
    int low = -1;
    int probe = 0;

    while (high - low > 1) 
    {                                  
        probe = (high + low) / 2;       
        if (table[probe].object_id < target)
        {
            low = probe;
        }
        else
        {
            high = probe;
        }
    }

    if (high == length || table[high].object_id != target) 
    {
        return -1;                     
    }
    else
    {
        return high;                    
    }
}
/**
* @brief	look up pump fault message descripiton based on the CAN object id
* @param	E_fault_msg_st *table: fault message table
* @param	s16 length: table length
* @param	s32 target: target object id
* @note     none
* @retval   none
*/
s16 lookup_e_fault_msg_object_id(const Controller_fault_msg_st *table, s16 length, s32 target)
{
    int high = length;
    int low = -1;
    int probe = 0;

    while (high - low > 1) 
    {                                  
        probe = (high + low) / 2;       
        if (table[probe].fault_id < target)
        {
            low = probe;
        }
        else
        {
            high = probe;
        }
    }

    if (high == length || table[high].fault_id != target) 
    {
        return -1;                     
    }
    else
    {
        return high;                    
    }
}

/**
* @brief	look up pump fault message descripiton based on the CAN object id
* @param	E_fault_msg_st *table: fault message table
* @param	s16 length: table length
* @param	s32 target: target object id
* @note     none
* @retval   none
*/
s32 lookup_unichar_object_id(const UniCharIcon *table, s16 length, s32 target)
{
    int high = length;
    int low = -1;
    int probe = 0;

    while (high - low > 1) 
    {                                  
        probe = (high + low) / 2;       
        if (table[probe].code < target)
        {
            low = probe;
        }
        else
        {
            high = probe;
        }
    }

    if (high == length || table[high].code != target) 
    {
        return -1;                     
    }
    else
    {
        return high;                    
    }
}

/**
* @brief	calculate the crc8
* @param	MemCanObjData* p_buffer: input byte array buffer
            size_t len: the buffer length
* @param	s16 length: table length
* @param	s32 target: target object id
* @note     none
* @retval   none
*/
U8 crc8_compute_bit(MemCanObjData* p_buffer, size_t len, U8 crc8)
{
    U8 i, u8Tmp = 0x00;                                    /* counter for 8 bit */
    while(len > 0)
    {
        crc8 ^= (U8)*p_buffer;                       /* xor element to shift register only once per loop, */
                                                   /* leads to a faster algorithm. */
        for(i=0; i<8; i++)
        {
            if((crc8 & 0x80) == 0x80)                     /* check msb of shift register */
            {
                u8Tmp = (crc8 << 1);
                u8Tmp = u8Tmp ^ (U8)CRC8_POLY;

                crc8 = u8Tmp;                          /* rotate shift register and xor CRC-Polynomial */
            }
            else
            {
                crc8 <<= 1;                            /* only rotate shift register */
            }
        }
        p_buffer++;                                  /* next element */
        len--;
    }
    return crc8;                                    /* result of shift register represents the check sum */
}


/***********************************************************************************************************************
*                             Copyright 2016 Linde Material Handling. All rights reserved.                             *
***********************************************************************************************************************/

